package com.wholeintech.zigbee.gw;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.wholeintech.dao.BoxInfoDao;
import com.wholeintech.entity.BoxInfo;
import com.wholeintech.utils.CommonIntent;
import com.wholeintech.utils.CommonUtil;
import com.wholeintech.entity.DeviceDb;
import com.wholeintech.utils.LogUtils;

import org.xutils.DbManager;
import org.xutils.ex.DbException;

import java.util.List;

public class DeviceManager {
    public final static int TYPE_MASTERBOX = 1000;//
    public final static int TYPE_TOPBOX = 1010;//
    public final static int TYPE_SWITCH = 1020;//
    public final static int TYPE_LIGHT = 1030;//
    public final static int TYPE_LIGHT_DIMMER = 1031;//
    public final static int TYPE_LIGHT_8 = 1033;//
    public final static int TYPE_CURTAIN = 1040;//
    public final static int TYPE_AIRCON = 1050;//
    public final static int TYPE_FLOOR_HEATING = 1060;//
    public final static int TYPE_FRESH_AIR = 1070;//
    public final static int TYPE_JBY = 1080;//
    public final static int TYPE_DOOR_SENSOR = 1090;//
    public final static int DEV_TYPE_AIR_CLEANER = 1100;//
    public final static int TYPE_PROJECT = 1110;
    public final static int TYPE_INFRARED = 1120;//zigbee
    public final static int TYPE_AIR_RADIO = 1130;//
    public final static int TYPE_SHOCK_SENSOR = 1140;//

    public final static int TYPE_IP2ZIGBEE_GW = 2010;//

    public static final int TYPE = 0x00;
    public static final int CMD = 0x01;
    public static final int DATA = 0x02;

    public static final int UART_CMD_None = 0;
    public static final int UART_CMD_eJoin = 1;
    public static final int UART_CMD_eRemove = 2;
    public static final int UART_CMD_eControl = 3;
    public static final int UART_CMD_eReadList = 4;
    public static final int UART_CMD_eClearList = 5;
    public static final int UART_CMD_eGetStatus = 6;
    public static final int UART_CMD_eHandshake = 7;
    public static final int UART_CMD_eBinding = 8;
    public static final int UART_CMD_eGetSecurityKey = 9;
    public static final int UART_CMD_eSetSecurityKey = 10;
    public static final int UART_CMD_eGetSerialNo = 11;
    public static final int UART_CMD_eSetSerialNo = 12;
    public static final int UART_CMD_eGetExtAddr = 13;
    public static final int UART_CMD_eGetPANID = 0x14;
    public static final int UART_CMD_eBoardCastReset = 0x16;
    public static final int UART_CMD_eRejectReq = 0x20;
    public static final int UART_CMD_Version = 0x21;
    public static final int UART_CMD_eZigBeeGwError = 0x23;
    public static final int UART_CMD_eGwBoardAllLightOn = 0x2A;
    public static final int UART_CMD_eGetAssoclistNum = 0x2f;
    public static final int UART_CMD_eManualClearAssoclist = 0x30;
    public static final int UART_CMD_eManualResetAssoclist = 0x31;
    public static final int UART_CMD_eGetMyDevOnlineNum = 0x32;
    public static final int UART_CMD_eManualTickClearAssoclist = 0x33;
    public static final int UART_CMD_BINDReqNwk = 0x34;
    public static final int UART_CMD_VoiceIndex = 0x55;
    public static final int UART_CMD_ZigBeeGwString = 0xfa;
    public static final int UART_CMD_eZigbeeReset = 0xfb;

    public static final int ZIGBEE_NETWORK = 1;
    public static final int BLE_NETWORK = 2;
    public static final int ETHERNET_NETWORK = 3;
    public static final int WIFI_NETWORK = 4;
    public static final int KNX_NETWORK = 6;
    public static final int MAX_AGAIN_COUNT = 3;

    public static final int DEVICE_MAC_ADDR_LEN = 8;
    public static final int DEVICE_ZIGBEE_DEVID_LEN = 12;
    public static final int DEVICE_ZIGBEE_LIGHT8_SUB_DEVID_LEN = 16;
    //Device status
    public static final int Dev_STATUS_eUnused = 0;
    public static final int Dev_STATUS_eNew = 1;
    public static final int Dev_STATUS_eDisconnect = 2;
    public static final int Dev_STATUSe_Connecting = 3;
    public static final int Dev_STATUS_eConnected = 4;
    public static final int Dev_STATUS_eReject = 5;
    public static final int Dev_STATUS_eLossconnect = 6;
    public static final int Dev_STATUS_eUnused1 = 0xff;

    public final static int DEV_RETRY_CTL_ = 10;  // 原本是5
    public final static int DELAY_LOAD_DEVICE = 250;
    private DeviceDb me;
    public static String flagLight8Devid;

    private String mac;
    private boolean debugFlag = true;
    private int rejectDevTryadd = 0;

    private String TAG = DeviceManager.class.getCanonicalName();
    private static final boolean dmDebug = true;
    private static String gZigbeeGWVersion;
    private static int mBoxZigBeeDevOnlineNum;
    private static int mBoxZigBeeDevAssocNum;
    private ZigBeeDataProcess mZBprocess;
    private static DeviceManager mDeviceManager;
    private Context mContext;

    private DeviceManager(ZigBeeDataProcess m, Context Context) {
        mZBprocess = m;
        mContext = Context;
    }

    public static DeviceManager getInstance(ZigBeeDataProcess m, Context Context) {
        if (mDeviceManager == null) {
            mDeviceManager = new DeviceManager(m, Context);
        }
        return mDeviceManager;
    }

    /**
     * 添加设备
     * @param data
     * @param mac
     * @param serialNo
     */
    public void add(DeviceDb data, String mac, String serialNo) {
        LogUtils.d(TAG,"===add===start==");
        if (data != null && data.getGwDevId() != null) {
            if (data.getGwDevId().length() == DEVICE_ZIGBEE_DEVID_LEN) {
                intentAddDevice(data.getGwDevId(), data.getDevId(), data.getMacAddr(), ETHERNET_NETWORK);
                return;
            }
        }

        byte[] macbyte = CommonUtil.macbytes(mac);
        byte[] serialNobyte = CommonUtil.serialNobytes(serialNo);

        byte[] SendData = CommonUtil.mergebyte(macbyte, serialNobyte);
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eJoin, SendData);
        LogUtils.d(TAG,"===add===name:"+data.getName()+"==devId:"+data.getDevId()+"==type:"+data.getType()+"==mac:"+mac+"==serialNo:"+serialNo);
    }

    /**
     * 移除设备
     * @param data
     * @param mac
     */
    public void remove(DeviceDb data, String mac) {
        if (data == null || data.getGwDevId() == null) {
            byte[] macbyte = CommonUtil.macbytes(mac);
            mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eRemove, macbyte);
        }
    }

    public void readList() {
        byte[] macbyte = {0};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eReadList, macbyte);
    }

    public void status(DeviceDb data, String mac) {
        if (data != null && data.getGwDevId() != null) {
            if ((data.getGwDevId().length() == DEVICE_ZIGBEE_DEVID_LEN)) {
                intentDevStatus(data.getGwDevId(), mac, ETHERNET_NETWORK);
                return;
            }
        }

        byte[] macbyte = CommonUtil.macbytes(mac);
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGetStatus, macbyte);
    }

    public void clearList() {
        byte[] clear = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eClearList, clear);
    }

    public void reset() {
        byte[] reset = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eZigbeeReset, reset);
    }

    public void getPanID() {
        byte[] getPanID = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGetPANID, getPanID);
    }

    public void allLightOn() {
        byte[] allLightOn = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGwBoardAllLightOn, allLightOn);
    }

    public void getMyDevOnlineNum() {
        byte[] getMyDevOnlineNum = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGetMyDevOnlineNum, getMyDevOnlineNum);
    }

    public void getAssoclistNum() {
        byte[] getAssoclistNum = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGetAssoclistNum, getAssoclistNum);
    }

    public void ManualZigBeeGwClearAssoclist() {
        byte[] clearAssoclist = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eManualClearAssoclist, clearAssoclist);
    }

    public void ManualResetAssoclist() {
        byte[] clearAssoclist = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eManualResetAssoclist, clearAssoclist);
    }

    public void version() {
        byte[] reset = {1};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_Version, reset);
    }

    public void systemReady() {
        byte[] ready = {(byte) 0xff};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eHandshake, ready);
    }

    public void getGwError() {
        byte[] getGwError = {0};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eZigBeeGwError, getGwError);
    }

    public void getZkey() {
        byte[] zKey = {(byte) 0xff};
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eGetSecurityKey, zKey);
    }

    public void bind(DeviceDb me, String mac, String devId, int group, int config) {
        if (me != null && me.getGwDevId() != null) {
            if (me.getGwDevId().length() == DEVICE_ZIGBEE_DEVID_LEN) {
                intentDevBind(me.getGwDevId(), mac, devId, group, config, ETHERNET_NETWORK);
                return;
            }
        }

        byte[] srcmacbyte = CommonUtil.macbytes(mac);
        byte[] destMacbyte = CommonUtil.serialNobytes(devId);
        byte[] data = new byte[destMacbyte.length + 2];
        System.arraycopy(destMacbyte, 0, data, 2, destMacbyte.length);
        data[0] = (byte) config;
        data[1] = (byte) group;
        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eBinding, CommonUtil.mergebyte(srcmacbyte, data));
    }

    public void securityKey(DeviceDb me, byte[] key) {
        if (me != null && me.getGwDevId() != null) {
            if (me.getGwDevId().length() == DEVICE_ZIGBEE_DEVID_LEN) {
                String zkey = new String(key);
                intentSecurityKeyGw(me.getGwDevId(), zkey, ETHERNET_NETWORK);
                Log.d(TAG, "intentSecurityKeyGw:" + " GwDevId: " + me.getGwDevId() + "zKey: " + zkey);
                return;
            }
        }

        mZBprocess.TxPackDataBuffer((byte) DeviceManager.UART_CMD_eSetSecurityKey, key);
    }

    private boolean deviceExist(DbManager db, byte[] data) {
        if (data.length < (DATA + DEVICE_MAC_ADDR_LEN))
            return false;
        byte[] bytes = CommonUtil.getSpecbyte(data, DATA, DEVICE_MAC_ADDR_LEN);
        bytes = CommonUtil.exchangebyte(bytes);
        mac = CommonUtil.bytesToHexString(bytes, 0, DEVICE_MAC_ADDR_LEN);
        try {
            me = db.selector(DeviceDb.class).where("macAddr", "=", mac).findFirst();
        } catch (DbException | NumberFormatException e) {
            e.printStackTrace();
        }
        if (me != null)
            return true;
        else
            return false;
    }

    private void updataDevStatus(DbManager db, int status, int enable) {
        if (status == Dev_STATUS_eConnected) {
            if (me.getPir() == -1) {
                me.setPir(0);
                me.setPanel(0);
            }
            Log.d(TAG, "Device Status:" + " MacAddr:" + me.getMacAddr() + " Name" + me.getName() + " Online ");
        } else {
            Log.d(TAG, "Device Status:" + " MacAddr:" + me.getMacAddr() + " Name" + me.getName() + " Offline ");
            me.setPir(-1);
            me.setPanel(-1);
        }

        try {
            me.setStatus(status);
            if (enable != 0)
                me.setRetryCnt(0);
            db.saveOrUpdate(me);
            /* 如果设备是一拖八网关则更新对应的设备状态 */
            if (me.getType() == TYPE_LIGHT_8) {
                List<DeviceDb> listLight_8_DevDb = db.selector(DeviceDb.class).where("netType", "=", DeviceManager.ZIGBEE_NETWORK)
                        .and("gwDevId", "=", me.getDevId()).findAll();
                if (listLight_8_DevDb == null)
                    Log.d(TAG, "This Light8 Gw has no subDevice!!");

                for (final DeviceDb item : listLight_8_DevDb) {
                    item.setPir(me.getPir());
                    item.setPanel(me.getPanel());
                    item.setStatus(status);
                    db.saveOrUpdate(item);
                    Log.d(TAG, "Device Light 8 DevId:" + item.getDevId() + " Name" + item.getName() + " status " + item.getStatus());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendBindConfig(DeviceDb data) {
        String bindStr;
        int config = 0;
        int index;

        Log.d(TAG, "Device bind start");
        try {
            if (data.getBindSw1() != null) {
                Log.d(TAG, "getBindGroup1:" + data.getBindSw1() + "lenth:" + data.getBindSw1().length());

                if (data.getBindSw1().length() > 12 + 2)
                    config = 1;
                index = data.getBindSw1().indexOf(":");
                if (index < 10) {
                    bindStr = data.getBindSw1().substring(0, index);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 0, config);
                    Log.d(TAG, "getBindGroup0 Data:" + bindStr);
                    Thread.sleep(50);
                    bindStr = data.getBindSw1().substring(index + 1);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 1, config);
                    Log.d(TAG, "getBindGroup1 Data:" + bindStr);
                } else {
                    bindStr = data.getBindSw1().substring(0, 12);
                    Log.d(TAG, "getBindSw0:" + bindStr);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 0, config);
                    if (config != 0) {
                        bindStr = data.getBindSw1().substring(13);
                        Log.d(TAG, "getBindSw1:" + bindStr);

                        Thread.sleep(100);
                        mDeviceManager.bind(data, data.getMacAddr(), bindStr, 1, config);
                    }
                }
            } else {
                bindStr = "NoDeviceBind";
                mDeviceManager.bind(data, data.getMacAddr(), bindStr, 0, config);
                mDeviceManager.bind(data, data.getMacAddr(), bindStr, 1, config);
            }
            Thread.sleep(100);
            config = 0;
            if (data.getBindSw2() != null) {
                Log.d(TAG, "getBindGroup2:" + data.getBindSw2() + "lenth:" + data.getBindSw2().length());

                if (data.getBindSw2().length() > 12 + 2)
                    config = 1;
                index = data.getBindSw2().indexOf(":");
                if (index < 10) {
                    bindStr = data.getBindSw2().substring(0, index);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 2, config);
                    Log.d(TAG, "getBindGroup2 Data:" + bindStr);
                    Thread.sleep(50);
                    bindStr = data.getBindSw2().substring(index + 1);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 3, config);
                    Log.d(TAG, "getBindGroup3 Data:" + bindStr);
                } else {
                    bindStr = data.getBindSw2().substring(0, 12);
                    Log.d(TAG, "getBindSw2:" + bindStr);
                    mDeviceManager.bind(data, data.getMacAddr(), bindStr, 2, config);
                    if (config != 0) {
                        bindStr = data.getBindSw2().substring(13);
                        Log.d(TAG, "getBindSw3:" + bindStr);

                        Thread.sleep(100);
                        mDeviceManager.bind(data, data.getMacAddr(), bindStr, 3, config);
                    }
                }
            } else {
                bindStr = "NoDeviceBind:NoDeviceBind";
                mDeviceManager.bind(data, data.getMacAddr(), bindStr, 2, config);
                mDeviceManager.bind(data, data.getMacAddr(), bindStr, 3, config);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updataDevData(byte[] data) {
        int type;
        int Rssi = data[4];
        int GwRssi = 0;
        if (data.length >= 6)
            GwRssi = data[5];

        Log.d(TAG, "Device CTL:" + " Mac:" + me.getDevId() + "  Name:" + me.getName() + "  data:" + CommonUtil.bytesToHexString(data, 0, data.length) + " Rssi:" + Rssi + "dBm" + " GwRssi:" + GwRssi + "dBm" + " Success ");
        type = me.getType();
        Log.d(TAG, "Device CTL:" + " Mac:" + me.getDevId() + "  Name:" + me.getName() + "  data:" + CommonUtil.bytesToHexString(data, 0, data.length) + " Rssi:" + Rssi + "dBm" + " GwRssi:" + GwRssi + "dBm" + " Success "+ "type: " + type);
        me.setPir(Rssi);
        me.setPanel(GwRssi);
        try {
            switch (type) {
                case TYPE_SWITCH:
                case TYPE_INFRARED: {
                    intentSwitchTrigger(me.getBoxId(), me.getDevId(), data[0], data[1]);
                    Log.d(TAG, "intentSwitchTrigger" + "************deviceId****************: " + me.getDevId() + "*********buttun**********: " + data[0]+"===type:"+data[1]);
                }
                break;
                case TYPE_LIGHT:
                    if (me.getSw() == ((byte) data[0])) {
                        me.setFbFlag(0);
                    } else {
                        me.setRetryCnt(0);
                        me.setFbFlag(1);
                    }
                    break;
                case TYPE_LIGHT_DIMMER:
                    int brg = 0 + (data[1] & 0x00ff);
                    if (me.getBrightness() == brg) {
                        me.setFbFlag(0);
                    } else {
                        me.setFbFlag(1);
                        me.setRetryCnt(0);
                    }
                    break;
                case TYPE_LIGHT_8:
                    me.setFbFlag(0);
                    break;
                case TYPE_CURTAIN: {
                    if (me.getCurtainState() == data[0] && me.getCurtainState2() == data[1]) {
                        me.setFbFlag(0);
                    } else {
                        me.setFbFlag(1);
                        me.setRetryCnt(0);
                    }
                }
                break;
                case TYPE_FLOOR_HEATING:
                    if (me.getSw() == data[0] && me.getMode() == data[1] && (me.getSetTemp() == (data[2] & 0x00ff))) {
                        me.setFbFlag(0);
                    } else {
                        me.setFbFlag(1);
                        me.setRetryCnt(0);
                    }
                    break;
                case TYPE_AIRCON:
                    if (me.getSw() == data[0] && me.getMode() == data[1] && (me.getSetTemp() == (data[2] & 0x00ff)) && me.getWind() == data[3]) {
                        me.setFbFlag(0);
                    } else {
                        me.setFbFlag(1);
                        me.setRetryCnt(0);
                    }
                    break;
                case TYPE_FRESH_AIR:
                    if (me.getSw() == data[0] && me.getWind() == data[1] && me.getMode() == data[2]) {
                        me.setFbFlag(0);
                    } else {
                        me.setFbFlag(1);
                        me.setRetryCnt(0);
                    }
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void saveDevData2Db(DbManager db, byte[] data) {
        int type = 0;
        Log.d(TAG, "Device CTL:" + " Mac:" + me.getMacAddr() + "  Name:" + me.getName() + "  data:" + CommonUtil.bytesToHexString(data, 0, data.length) + " Success ");
        type = me.getType();
        Log.d(TAG, "Device CTL:" + " Mac:" + me.getMacAddr() + "  Name:" + me.getName() + "  data:" + CommonUtil.bytesToHexString(data, 0, data.length) + " Success " + "type: " + type);

        switch (type) {
            case TYPE_SWITCH:
                break;
            case TYPE_LIGHT:
                me.setSw((byte) data[0]);
                break;
            case TYPE_LIGHT_DIMMER:
                int brg = 0 + (data[1] & 0x00ff);
                me.setSw((byte) data[0]);
                me.setBrightness(brg);
                break;
            case TYPE_CURTAIN: {
                me.setCurtainState(data[0]);
                me.setCurtainState2(data[1]);
            }
            break;
            case TYPE_FLOOR_HEATING:
            case TYPE_AIRCON:
                me.setSw(data[0]);
                me.setMode(0 + data[1]);
                me.setSetTemp(0 + data[2]);
                me.setWind((byte) data[3]);
                break;
        }
        try {
            db.saveOrUpdate(me);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 处理底层上报的协议数据
     * @param data
     * @return
     */
    public int DeviceFbProc(byte[] data) {
        DbManager db = CommonUtil.MyDbUtils();
        int ret = 0;
        try {
            switch (data[CMD]) {
                case UART_CMD_eJoin: {
                    if (!deviceExist(db, data))
                        break;
                    if (data.length > 10) {
                        if (data[DATA + DEVICE_MAC_ADDR_LEN] == Dev_STATUS_eConnected) {
                            Log.d(TAG, "==DeviceFbProc==Device macaddr:" + me.getMacAddr() + "ejoin Success ");
                            if (me.getType() == DeviceManager.TYPE_SWITCH || me.getType() == DeviceManager.TYPE_INFRARED) {
                                sendBindConfig(me);
                            }
                            if (rejectDevTryadd > 0)
                                rejectDevTryadd--;
                        } else {
                            if (!deviceExist(db, data)) {
                                Log.d(TAG, "==DeviceFbProc==Device macaddr:" + mac + "ejoin False ");
                                break;
                            }
                        }
                        updataDevStatus(db, data[DATA + DEVICE_MAC_ADDR_LEN], 1);
                    }
                }
                break;
                case UART_CMD_eRemove: {
                    Log.d(TAG, " ==DeviceFbProc==Device macaddr:" + mac + " Remove dev successul ");
                }
                break;
                case UART_CMD_eControl: {
                    if (!deviceExist(db, data))
                        break;
                    if (((data[TYPE]) & (byte) 0x0F) != 0) {
                        if (((data[TYPE]) & (byte) 0x07) != 0) {
                            updataDevStatus(db, Dev_STATUS_eLossconnect, 0);
                            CommonUtil.sendBroadcastMsg(mContext,CommonIntent.ACTION_DEV_DEVCHANAGE,me.getBoxId(),me.getDevId(),me.getType(),false,null);
                            Log.e(TAG,"sendBroadcastMsg===6");
                            Log.d(TAG, "==DeviceFbProc==Device macaddr:"+mac+" Disconnect ");
                        }
                        return ret;
                    } else if (data[TYPE] == (byte) 0x80) {
                        updataDevStatus(db, Dev_STATUS_eConnected, 1);
                        byte[] ctrData = CommonUtil.getSpecbyte(data, DATA + DEVICE_MAC_ADDR_LEN, (data.length - (DATA + DEVICE_MAC_ADDR_LEN)));
                        updataDevData(ctrData);
                    } else {
                        updataDevStatus(db, Dev_STATUS_eConnected, 1);
                        byte[] ctrData = CommonUtil.getSpecbyte(data, DATA + DEVICE_MAC_ADDR_LEN, 4);
                        saveDevData2Db(db, ctrData);
                        Log.d(TAG, "==DeviceFbProc==9999999999999999999999999999999999999999999999999");
                    }

                    db.saveOrUpdate(me);
                    //
                    if(me.getType() == 1033){
                        //一拖8网关设备
                        //getDevId   getGwDevId
                        CommonUtil.sendBroadcastMsg(mContext,CommonIntent.ACTION_DEV_DEVCHANAGE,me.getBoxId(),flagLight8Devid,me.getType(),false,null);
                        Log.e(TAG,"sendBroadcastMsg===7");
                    }else{
                        //getDevId   getGwDevId
                        CommonUtil.sendBroadcastMsg(mContext,CommonIntent.ACTION_DEV_DEVCHANAGE,me.getBoxId(),me.getDevId(),me.getType(),false,null);
                        Log.e(TAG,"sendBroadcastMsg===8");
                    }

                    Log.d(TAG, "==DeviceFbProc==**************: "+me.getDevId() + "getType: " + me.getType());//cx
                }
                break;
                case UART_CMD_eReadList:
                    break;
                case UART_CMD_eClearList:
                    break;
                case UART_CMD_eGetStatus: {
                    ret = 1;
                    byte[] ctrData = CommonUtil.getSpecbyte(data, DATA + DEVICE_MAC_ADDR_LEN, (data.length - (DATA + DEVICE_MAC_ADDR_LEN)));
                    if (!deviceExist(db, data))
                        break;
                    if (((data[TYPE]) & (byte) 0x0f) != 0 || (data[DATA + DEVICE_MAC_ADDR_LEN + 4] == (byte) 0xff)) {
                        updataDevStatus(db, Dev_STATUS_eLossconnect, 0);
                    } else {
                        if (me.getType() == DeviceManager.TYPE_SWITCH || me.getType() == DeviceManager.TYPE_INFRARED) {
                            sendBindConfig(me);
                        } else if (me.getType() == DeviceManager.TYPE_IP2ZIGBEE_GW) {
                            //TODO
                            intentSecurityKeyGw(me.getGwDevId(), me.getDevCfg(), ETHERNET_NETWORK);
                        } else {
                            updataDevData(ctrData);
                        }
                        me.setFbFlag(0);
                        updataDevStatus(db, Dev_STATUS_eConnected, 1);
                    }

                    CommonUtil.sendBroadcastMsg(mContext,CommonIntent.ACTION_DEV_DEVCHANAGE,me.getBoxId(),me.getDevId(),me.getType(),false,null);
                    Log.e(TAG,"sendBroadcastMsg===9");
                }
                break;
                case UART_CMD_eHandshake: {
                    Log.d(TAG, "Zigbee GW exist");
                }
                break;
                case UART_CMD_BINDReqNwk: {
                    Log.d(TAG, "Zigbee GW Rvc Bind Req Nwk");
                }
                break;
                case UART_CMD_eGetSecurityKey: {
                    String zKey;
                    BoxInfoDao boxInfoDao = new BoxInfoDao(mContext);
                    List<BoxInfo> boxInfo = boxInfoDao.getBoxInfoList();

                    if (boxInfo == null) {
                        Log.d(TAG, "Zigbee zkey NUll: ");
                        return 0;
                    }
                    byte[] bZkey = CommonUtil.getSpecbyte(data, DATA, 16);
                    zKey = boxInfo.get(0).getZkey();
                    String fbZkey = new String(bZkey);
                    if (zKey != null)
                        if (fbZkey.equals(boxInfo.get(0).getZkey())) {
                            Log.d(TAG, "Zigbee zkey ready: " + boxInfo.get(0).getZkey());
                        } else {
                            securityKey(null, boxInfo.get(0).getZkey().getBytes());
                            Log.d(TAG, "Zigbee zkey updata: " + boxInfo.get(0).getZkey() + fbZkey);
                        }
                }
                break;
                case UART_CMD_eRejectReq: {
                    if (data.length < 10)
                        break;
                    if (!deviceExist(db, data)) {
                        if (data.length > 15) {
                            String sData = new String(data);
                            Log.d(TAG, "Zigbee GateWay Program data:" + sData);
                        }
                        Log.d(TAG, "Device macaddr:" + mac + "none added to Db");
                        break;
                    }
                    add(me, mac, me.getDevId());
                    rejectDevTryadd++;
                    if (rejectDevTryadd > 20) {
                        DbCheck();
                        rejectDevTryadd = 0;
                    }
                    Log.d(TAG, "Reject req Device macaddr:" + mac + "try add again");
                }
                break;
                case UART_CMD_eBinding: {
                    byte[] bindInfo = CommonUtil.getSpecbyte(data, data.length - 3, 2);
                    Log.d(TAG, "BindSwInfo:" + CommonUtil.bytesToHexString(bindInfo, bindInfo.length));
                }
                break;
                case UART_CMD_eGetPANID: {
                    if (data.length < DATA + 4) {
                        Log.d(TAG, "!!!!zigbee data<DATA + 4!!!!");
                        break;
                    }
                    byte[] bytePANID = CommonUtil.getSpecbyte(data, DATA, 4);
                    Log.d(TAG, "zigbee NV PANID :" + CommonUtil.bytesToHexString(bytePANID, bytePANID.length));

                    byte[] byteNIBPANID = CommonUtil.getSpecbyte(data, DATA + 4, 4);
                    Log.d(TAG, "zigbee NIB PANID :" + CommonUtil.bytesToHexString(byteNIBPANID, byteNIBPANID.length));
                    if (data.length < DATA + 8) {
                        Log.d(TAG, "!!!!zigbee data<DATA + 8!!!!");
                        break;
                    }
                    byte[] bytezgCfgPANID = CommonUtil.getSpecbyte(data, DATA + 8, 4);
                    Log.d(TAG, "zigbee Config PANID :" + CommonUtil.bytesToHexString(bytezgCfgPANID, bytezgCfgPANID.length));
                    if (data.length < DATA + 12) {
                        Log.d(TAG, "!!!!zigbee data<DATA + 12!!!!");
                        break;
                    }
                    byte[] byteDefChList = CommonUtil.getSpecbyte(data, DATA + 12, 4);
                    Log.d(TAG, "zigbee DefChList :" + CommonUtil.bytesToHexString(byteDefChList, byteDefChList.length));
                    if (data.length < DATA + 16) {
                        Log.d(TAG, "!!!!zigbee data<DATA + 16!!!!");
                        break;
                    }
                    byte[] byteNvChList = CommonUtil.getSpecbyte(data, DATA + 16, 4);
                    Log.d(TAG, "zigbee byteNvChList :" + CommonUtil.bytesToHexString(byteNvChList, byteNvChList.length));
                    if (data.length < DATA + 20) {
                        Log.d(TAG, "!!!!zigbee data<DATA + 20!!!!");
                        break;
                    }
                    byte[] devState = CommonUtil.getSpecbyte(data, DATA + 20, 4);
                    Log.d(TAG, "zigbee devState :" + CommonUtil.bytesToHexString(devState, devState.length));
                }
                break;
                case UART_CMD_eBoardCastReset: {
                    if (!deviceExist(db, data))
                        break;

                    byte[] boardResetDevData = CommonUtil.getSpecbyte(data, DATA + DEVICE_MAC_ADDR_LEN, 5);
                    int boardResetDevRssi = boardResetDevData[4];
                    Log.d(TAG, "BoardCastRst:"
                            + " Mac:" + me.getMacAddr()
                            + "  Name:" + me.getName()
                            + "  data:" + CommonUtil.bytesToHexString(boardResetDevData, 0, boardResetDevData.length)
                            + " Rssi:" + boardResetDevRssi
                            + "Bm Success ");

                }
                break;
                case UART_CMD_Version: {
                    byte[] version = CommonUtil.getSpecbyte(data, DATA, data.length - 2);
                    String sVersion = new String(version, "UTF-8");
                    /* TDDO:暂时取定长字符串解决，以后再修改版本号为不定长显示 */
                    sVersion = sVersion.substring(0, 15);
                    Log.d(TAG, "zigbee soft version :" + sVersion + "len:" + sVersion.length());
                    if (!sVersion.equals(getZigbeeGwVersionString())) {
                        setZigbeeGwVersionString(sVersion);
                        if (dmDebug) {
                            Log.d(TAG, "sVersion:" + sVersion);
                            Log.d(TAG, "getZigbeeGwVersionString:" + getZigbeeGwVersionString());
                        }
                    }

                    sVersion = CommonUtil.getZigbeeGWVersion();
                    if (sVersion.length() > 15) {
                        sVersion = sVersion.substring(0, 15);
                    }

                    if (dmDebug) {
                        Log.d(TAG, "getZigbeeGWVersion:" + sVersion + "len:" + sVersion.length());
                    }
                    if (!(getZigbeeGwVersionString().equals(sVersion))) {
                        CommonUtil.setZigbeeGWVersion(getZigbeeGwVersionString());
                        sVersion = CommonUtil.getZigbeeGWVersion();
                        if (sVersion.length() > 15) {
                            sVersion = sVersion.substring(0, 15);
                        }
                        if (!(getZigbeeGwVersionString().equals(sVersion))) {
                            Log.d(TAG, "zigbee version setprop failed!!");
                        } else {
                            if (dmDebug) {
                                Log.d(TAG, "zigbee version setprop success!!");
                            }
                        }
                    }
                }
                break;
                case UART_CMD_eZigBeeGwError: {
                    byte[] ZigBeeGwError = CommonUtil.getSpecbyte(data, DATA, data.length);
                    String sZigBeeGwError = new String(ZigBeeGwError);
                    Log.d(TAG, "ZigBeeGwError:" + sZigBeeGwError);
                }
                break;
                case UART_CMD_eGetAssoclistNum: {
                    byte[] getAssoclistNum = CommonUtil.getSpecbyte(data, DATA, data.length - 2);
                    Log.d(TAG, "GetAssoclistNum=" + CommonUtil.bytesToHexString(getAssoclistNum, 1));
                    setBoxZigBeeDevAssocNum(getAssoclistNum[0]);
                }
                break;
                case UART_CMD_eManualClearAssoclist: {
                    Log.d(TAG, "!!!!!!!ManualZigBeeGwClearAssoclist!!!!!!!");
                }
                break;
                case UART_CMD_eManualResetAssoclist: {
                    Log.d(TAG, "!!!!!!!ManualResetAssoclist!!!!!!!");
                }
                break;
                case UART_CMD_eGetMyDevOnlineNum: {
                    byte[] getMyDevOnlineNum = CommonUtil.getSpecbyte(data, DATA, data.length - 2);
                    Log.d(TAG, "GetgetMyDevOnlineNum=" + CommonUtil.bytesToHexString(getMyDevOnlineNum, 1));
                    setBoxZigBeeDevAssocNum(getMyDevOnlineNum[0]);
                }
                break;
                case (byte) UART_CMD_ZigBeeGwString: {
                    byte[] GwString = CommonUtil.getSpecbyte(data, DATA, data.length - 2);
                    String sGwString = new String(GwString);
                    Log.d(TAG, "GwString=" + sGwString);
                }
                break;
                case UART_CMD_VoiceIndex: {
                    byte[] VoiceIndex = CommonUtil.getSpecbyte(data, DATA, data.length - 2);
                    Log.d(TAG, "UART_CMD_VoiceIndex=:0x" + CommonUtil.bytesToHexString(VoiceIndex, VoiceIndex.length));
                    intentVoice2Index(CommonUtil.getUnsignedByte(data[DATA]));
                }
                break;
                default:
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ret;
    }

    public void DbCheck() {
        DbManager db = CommonUtil.MyDbUtils();
        BoxInfoDao boxinfoDao = new BoxInfoDao(mContext);
        List<BoxInfo> boxInfo = boxinfoDao.getBoxInfoList();

        if (db == null)
            return;
        try {
            List<DeviceDb> listZigBeeDb = db.findAll(DeviceDb.class);
            if (listZigBeeDb == null) {
                Log.d(TAG, "Nothing hardware device.");
                return;
            }
            for (final DeviceDb item : listZigBeeDb) {

                if (item.getNetType() == DeviceManager.ZIGBEE_NETWORK) {
                    if (boxInfo.get(0).getRegionId() != item.getRegionId()) {
                        item.setStatus(DeviceManager.Dev_STATUS_eConnected);
                        db.saveOrUpdate(item);
                        continue;
                    }
                    add(me, item.getMacAddr(), item.getDevId());
                    item.setStatus(0);
                    item.setPir(-1);
                    item.setFbFlag(0);
                    item.setRetryCnt(0);
                    try {
                        Thread.sleep(DELAY_LOAD_DEVICE);///////////// lDelayoad
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                db.saveOrUpdate(item);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void DbCheckStatus(int enable) {
        DbManager db = CommonUtil.MyDbUtils();
        if (db == null)
            return;
        try {
            List<DeviceDb> zigBeeDbList = db.findAll(DeviceDb.class);
            if (zigBeeDbList == null) {
                Log.d(TAG, "Nothing hardware device.");
                return;
            }
            for (final DeviceDb item : zigBeeDbList) {
                if ((item.getNetType() == DeviceManager.ZIGBEE_NETWORK) && (item.getStatus() != Dev_STATUS_eConnected || enable != 0)) {
                    status(item, item.getMacAddr());
                    if(debugFlag)Log.d(TAG, "item devid:" + item.getDevId() + " status:" + item.getStatus());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public int devStatusRecovery() {
        DbManager db = CommonUtil.MyDbUtils();
        int Sum = 0;
        systemReady();
        BoxInfoDao boxinfoDao = new BoxInfoDao(mContext);
        List<BoxInfo> boxInfo = boxinfoDao.getBoxInfoList();

        if (db == null)
            return -1;
        try {
            List<DeviceDb> zigBeeDbList = db.findAll(DeviceDb.class);
            if (zigBeeDbList == null) {
                Log.d(TAG, "Nothing hardware device.");
                return 0;
            }
            for (final DeviceDb item : zigBeeDbList) {
                if (boxInfo.get(0).getRegionId() != item.getRegionId()) {
                    item.setStatus(DeviceManager.Dev_STATUS_eConnected);
                    db.saveOrUpdate(item);
                    continue;
                }

                if (item.getNetType() == DeviceManager.ZIGBEE_NETWORK) {
                    item.setFbFlag(0);
                    item.setRetryCnt(0);
                    status(item, item.getMacAddr());
                }

                db.saveOrUpdate(item);
                Sum++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Sum;
    }

    /**
     * 设备超时检测(网络信号不好时，会重发控制指令）
     * @param deviceControl
     * @return
     */
    public int DevFbCtlTimeout(DeviceControl deviceControl) {
        DbManager db = CommonUtil.MyDbUtils();
        BoxInfoDao boxinfoDao = new BoxInfoDao(mContext);
        List<BoxInfo> boxInfo = boxinfoDao.getBoxInfoList();

        int retry;
        int retryNum = 0;
        int devType;
        try {
            List<DeviceDb> listZigBeeDb = db.selector(DeviceDb.class).where("netType", "=", DeviceManager.ZIGBEE_NETWORK)
                    .and("status", "=", DeviceManager.Dev_STATUS_eConnected).findAll();
            if (listZigBeeDb == null) {
                Log.d(TAG, "Nothing hardware device.");
                return 0;
            }
            for (final DeviceDb item : listZigBeeDb) {
                devType = item.getType();
                if (boxInfo.get(0).getRegionId() != item.getRegionId())
                    return 0;

                if (devType == DeviceManager.TYPE_SWITCH
                        || devType == DeviceManager.TYPE_INFRARED
                        || (item.getDevId().length() == DeviceManager.DEVICE_ZIGBEE_LIGHT8_SUB_DEVID_LEN))
                    continue;
                if (item.getFbFlag() == 0)
                    continue;
                //add by levin 如果设备不在线，则不进行重发
                if (DeviceManager.Dev_STATUS_eDisconnect == item.getStatus())
                    continue;
                retry = item.getRetryCnt();
                if (retry >= DEV_RETRY_CTL_ ) {    //retry over time set device status Disconnect
                    item.setPir(-1);
                    // TODO zigbee gw add new cmd setting this device status Disconnect in The device status table( mdevLinkStatus )
                    item.setRetryCnt(0);
                    db.saveOrUpdate(item);
                    continue;
                }
                retry++;
                retryNum++;
                item.setRetryCnt(retry);
                db.saveOrUpdate(item);
                Log.d(TAG, "retry ctl devid:" + item.getDevId() + "retry num :" + retry +"type:"+item.getType());
                if(retry <= 5)
                    deviceControl.control(item);
            }
            Log.e(TAG, "DevFbCtlTimeout :" + "retry num :" + retryNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return retryNum;
    }

    public void intentSwitchTrigger(String boxId, String devId, int button, int type) {
        Intent mIntent = new Intent(CommonIntent.ACTION_SWITCH_TRIGGER);
        mIntent.putExtra("boxId", boxId);
        mIntent.putExtra("deviceId", devId);
        mIntent.putExtra("button", button);
        mIntent.putExtra("type", type);
        mContext.sendBroadcast(mIntent);
    }

    public void intentVoice2Index(int index) {
        Intent mIntent = new Intent(CommonIntent.ACTION_LOCAL_VOICE);
        mIntent.putExtra("text", index);
        mContext.sendBroadcast(mIntent);
    }

    public void intentAddDevice(String gwDevId, String devId, String macAddr, int netType) {
        Intent mIntent = new Intent(CommonIntent.ACTION_DEV_ADD);
        mIntent.putExtra("gwDevId", gwDevId);
        mIntent.putExtra("network", netType);
        mIntent.putExtra("deviceId", devId);
        mIntent.putExtra("macAddr", macAddr);
        mContext.sendBroadcast(mIntent);
    }

    public void intentDevBind(String gwDevId, String macAddr, String bindDevId, int group, int config, int netType) {
        Intent mIntent = new Intent(CommonIntent.ACTION_DEV_BIND);
        mIntent.putExtra("gwDevId", gwDevId);
        mIntent.putExtra("macAddr", macAddr);
        mIntent.putExtra("network", netType);
        mIntent.putExtra("bindDevId", bindDevId);
        mIntent.putExtra("group", group);
        mIntent.putExtra("config", config);
        mContext.sendBroadcast(mIntent);
    }

    public void intentDevStatus(String gwDevId, String macAddr, int netType) {
        Intent mIntent = new Intent(CommonIntent.ACTION_DEV_STATUS);
        mIntent.putExtra("gwDevId", gwDevId);
        mIntent.putExtra("network", netType);
        mIntent.putExtra("macAddr", macAddr);
        mContext.sendBroadcast(mIntent);
        Log.d(TAG, "intentDevStatus:" + gwDevId);
    }

    public void intentSecurityKeyGw(String gwDevId, String zKey, int netType) {
        Intent mIntent = new Intent(CommonIntent.ACTION_DEV_SECURITYKEY);
        mIntent.putExtra("key", zKey);
        Log.d(TAG, "ACTION_DEV_SECURITYKEY zKey: " + zKey);            //Add by hy,2018/03/30
        mIntent.putExtra("gwDevId", gwDevId);
        mIntent.putExtra("network", netType);
        mContext.sendBroadcast(mIntent);
    }

    public static void setZigbeeGwVersionString(String strZigbeeGWVersion) {
        gZigbeeGWVersion = strZigbeeGWVersion;
    }

    public static String getZigbeeGwVersionString() {
        return gZigbeeGWVersion;
    }

    public static void setBoxZigBeeDevAssocNum(int BoxZigBeeDevAssocNum) {
        mBoxZigBeeDevAssocNum = BoxZigBeeDevAssocNum;
    }

    public static int getBoxZigBeeDevAssocNum() {
        return mBoxZigBeeDevAssocNum;
    }

    public static void setBoxZigBeeDevOnlineNum(int BoxZigBeeDevOnlineNum) {
        mBoxZigBeeDevOnlineNum = BoxZigBeeDevOnlineNum;
    }

    public static int getBoxZigBeeDevOnlineNum() {
        return mBoxZigBeeDevOnlineNum;
    }
}
